package com.tao.innerclass;

/**
 * 匿名内部类
 */

public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer02 outer02 = new Outer02();
        outer02.method();
    }
}

class Outer02{//外部类
    private int n1 = 10;
    public void method(){

        //为什么要使用匿名内部类呢？
        //如果想使用IA接口，并创建对象，对于我们的传统方式，就是要写一个类，并实现接口，再创建对象
        //而每次想创建对象都要写一个类，所以为了简化，在类只需要使用一次，后面不再使用的时候，
        //可以使用匿名内部类来简化开发

        //基于接口的匿名内部类，与接口有关
        //底层会创建匿名内部类
        IA tiger = new IA(){//这句代码底层是：class Outer02$1 implements IA{}
            //这个地方tiger的编译类型是IA，运行类型是匿名内部类Outer02$1
            //jdk底层在创建匿名内部类Outer01$1时，立即就创建了Outer02$1实例，并把地址返回给tiger
            //匿名内部类使用一次就不能再使用
            @Override
            public void cry() {
                System.out.println("老虎叫唤。。。");
            }
        };
        System.out.println("tiger 的运行类型=" + tiger.getClass());
        tiger.cry();//动态绑定


        //基于类的匿名内部类，与继承有关
        Father tao = new Father("tao"){//底层：class Outer04$2 extends Father{
            //tao的编译类型是Father，运行类型是匿名内部类Outer02$2
            //("tao")参数列表会返回构造器，调用父类的构造器
            @Override
            public void test() {
                System.out.println("匿名内部类重写了test方法");
            }
        };
        tao.test();


        //基于抽象类的匿名内部类
        //必须先实现抽象类的所有方法，上面的非抽象类就可以不用实现类中所有方法
        Animal animal = new Animal(){
            @Override
            void eat() {
                System.out.println("小狗吃饭。。。");
            }
        };
        animal.eat();
    }

}

interface IA{
    public void cry();
}


class Father{
    public Father(String name) {//构造器
        System.out.println("接收到name=" + name);
    }
    public void test(){

    }
}

abstract class Animal{
    abstract void eat();
}